﻿using Microsoft.WindowsAzure.Storage.Table;
using POC.Azure.Model;
using POC.Azure.Storage;
using POC.Configuration;

using POC.Loggers.Model;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace POC
{

    public enum LogEntryType
    {
        Error = 1,
        Warning = 2,
        Information = 4,
        SuccessAudit = 8,
        FailureAudit = 16,
        Debug = 32,
        Trace = 64
    }
    public  class Diagnostics
    {
        IStorageRespository<LogEntry> _repository;
        static Diagnostics _logger;
        static string TableName = "ApplicationLogEntry";
        protected List<Task> tasks;
        bool async = false;
        public static Diagnostics Logger
        {
            get
            {
                if (_logger == null)
                {
                    AzureAccount account = GetLocalWorkingAccount();
                    var repository = new TableStorageRespository<LogEntry>(account, TableName);                    
                    repository.InitializeRepository();
                    _logger = new Diagnostics(repository);
                }
                return _logger;
            }
        }
        private Diagnostics()
        {
            tasks = new List<Task>();
            async =  AppSetting.Instance.IsAsyncOperation;
        }
        private static AzureAccount GetLocalWorkingAccount()
        {
            bool isLocalAccount = AppSetting.Instance.IsLocalAccount;
            AzureAccount account = new AzureAccount(isLocalAccount);
            // Local Account
            return account;
        }
        public Diagnostics(IStorageRespository<LogEntry> repository)
        {  
            _repository = repository;
            tasks = new List<Task>();
            async = AppSetting.Instance.IsAsyncOperation;
        }
        public void PutEntry(LogEntry entry, bool async = false)
        {
           //var task = _repository.PutEntry(entry, async);
           //if (task != null) // Task will be null for all synchronous call
           //{
           //    this.tasks.Add(task);
           //    task.ContinueWith(t => tasks.Remove(t));
           //}
        }
        public void Flush(bool async = false)
        {
            if (async)
                Task.WaitAll(tasks.ToArray());            
        }
        public void WriteEntry(string source, string message,  long errorCode, LogEntryType category = LogEntryType.Information, int eventId=100, TraceEventType eventType = TraceEventType.Information)
        {
            LogEntry entry = new LogEntry(message, category.ToString());
            entry.EventID = eventId;
            entry.EventType = (int)eventType;
            entry.ErrorCode = errorCode;
            entry.LogSource = source;
            PutEntry(entry, async);
        }
         ~Diagnostics()
        {
            Flush();
        }
    }
}
